package ide.ccf.ccdesigner.cpp.wizards;

import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.operation.*;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import java.io.*;

import org.eclipse.ui.*;
import org.eclipse.ui.ide.IDE;

import ide.ccf.ccdesigner.cpp.wizards.pages.DesignerFormsWizardPage;

/**
 * 这是一个新建向导范例。它的作用是在提供的指定容器中创建一个新的文件资源。
 * 如果一个容器资源（一个文件夹或者一个项目）在向导打开时已经在工作台选定，那个该容器资源将会被作为目标容器。
 * 本向导创建一个扩展名为“ui”的文件。如果有注册为打开该扩展的多页编辑器，那么编辑器将会打开该文件。
 *
 */
public class DesignerFormsWizard extends Wizard implements INewWizard
{
	private DesignerFormsWizardPage page;
	private ISelection selection;
	public static final String TEMPLATE_LOCATION = "/ide/ccf/ccdesigner/cpp/wizards/templates";	// 模板路径

	/**
	 * 构造器
	 */
	public DesignerFormsWizard()
	{
		super();
		setNeedsProgressMonitor(true);
	}

	/**
	 * 添加页面到向导
	 */
	public void addPages()
	{
		page = new DesignerFormsWizardPage(selection);
		addPage(page);
	}

	/**
	 * 向导完成处理。
	 * 这个方法在向导“完成”按下时调用。将创建一个操作，并使用向导作为执行上下文运行它。
	 */
	public boolean performFinish()
	{
		final String containerName = page.getContainerName();
		final String fileName = page.getFileName();
		final String template = page.getTemplateName();
		
		IRunnableWithProgress op = new IRunnableWithProgress()
		{
			public void run(IProgressMonitor monitor) throws InvocationTargetException
			{
				try
				{
					doFinish(containerName, fileName, template, monitor);
				} 
				catch (CoreException e)
				{
					throw new InvocationTargetException(e);
				} 
				finally
				{
					monitor.done();
				}
			}
		};
		try
		{
			getContainer().run(true, false, op);
		} 
		catch (InterruptedException e)
		{
			return false;
		} 
		catch (InvocationTargetException e)
		{
			Throwable realException = e.getTargetException();
			MessageDialog.openError(getShell(), "Error", realException.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * 向导完成的真正执行方法。
	 * 本方法将寻找一个容器，创建文件（如果文件不存在）或者直接替换文件内容，并使用编辑器打开该文件。
	 * @param containerName
	 * @param fileName
	 * @param template
	 * @param monitor
	 * @throws CoreException
	 */
	private void doFinish(String containerName, String fileName, String template, IProgressMonitor monitor) throws CoreException
	{
		monitor.beginTask("创建文件：" + fileName, 2);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IResource resource = root.findMember(new Path(containerName));
		
		if (!resource.exists() || !(resource instanceof IContainer))
		{
			throwCoreException("容器\"" + containerName + "\"不存在。");
		}
		
		IContainer container = (IContainer) resource;
		final IFile file = container.getFile(new Path(fileName));
		try
		{
			InputStream stream = getClass().getClassLoader().getResourceAsStream(template);
			if (!file.exists())
				file.create(stream, true, monitor);
			stream.close();
		} 
		catch (IOException e)
		{
		}
		
		monitor.worked(1);
		monitor.setTaskName("打开文件以编辑。。。");
		
		getShell().getDisplay().asyncExec(new Runnable()
		{
			public void run()
			{
				IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
				try
				{
					IDE.openEditor(page, file, true);
				} 
				catch (PartInitException e)
				{
				}
			}
		});
		monitor.worked(1);
	}

	/**
	 * 致命错误时抛出异常
	 * @param message
	 * @throws CoreException
	 */
	private void throwCoreException(String message) throws CoreException
	{
		IStatus status = new Status(IStatus.ERROR, "ide.ccf.ccdesigner", IStatus.OK, message, null);
		throw new CoreException(status);
	}

	/**
	 * 尝试初始化工作台接收的选择
	 * 
	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
	 */
	public void init(IWorkbench workbench, IStructuredSelection selection)
	{
		this.selection = selection;
	}
}